import axios from 'axios'
import type { AxiosRequestConfig, AxiosInstance, AxiosTransformer } from 'axios'

import coreTool from '/@/tool/coreTool'

import { message } from 'ant-design-vue'
import { router } from '/@/router'
import { PageEnum } from '/@/enums/pageEnum'

const transformRequest: AxiosTransformer = (data) => {
  if (coreTool.httpRequestBodyEncode) {
    return coreTool.encodeAES(JSON.stringify(data), coreTool.ls.get!('coreAesKey') ? coreTool.aesKeyDecode ? coreTool.ls.get!('coreAesKey') : coreTool.decodeRSAByPrivateKey(coreTool.ls.get!('coreAesKey'), coreTool.privateKey) : coreTool.aesKey)
  }
  return JSON.stringify(data)
}

const transformResponse: AxiosTransformer = (data) => {
  try {
    if (coreTool.httpResponseBodyDecode) {
      return JSON.parse(coreTool.decodeAES(JSON.parse(data).msg, coreTool.ls.get!('coreAesKey') ? coreTool.aesKeyDecode ? coreTool.ls.get!('coreAesKey') : coreTool.decodeRSAByPrivateKey(coreTool.ls.get!('coreAesKey'), coreTool.privateKey) : coreTool.aesKey))
    }
    return JSON.parse(data)
  } catch (error) {
    return data
  }
}

const config: AxiosRequestConfig = {
  baseURL: '/api/',
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  // 请求体加密
  transformRequest: transformRequest,
  // 响应体解密
  transformResponse: transformResponse,
}

const coreAxios: AxiosInstance = axios.create(config)

let isFirst400: boolean = true
let isFirst401: boolean = true
let isFirst404: boolean = true
let isFirst408: boolean = true
let isFirst500: boolean = true
let isFirst502: boolean = true
let isFirst504: boolean = true
let isFirst: boolean = true

// 请求拦截器
coreAxios.interceptors.request.use(config => {
  if (coreTool.authorizationInterceptor) {
    config.headers.common['Authorization'] = coreTool.encodeRSAByPublicKey(`${config.headers.common['Authorization']}${+new Date()}`, coreTool.publicKey)
    return config
  } else {
    return config
  }
}, error => {
  if (coreTool.authorizationInterceptor) {
    return Promise.reject(error)
  } else {
    return Promise.reject(error)
  }
})

// 响应拦截器
coreAxios.interceptors.response.use(res => {
  if (coreTool.authorizationInterceptor) {
    return res
  } else {
    return res
  }
}, error => {
  if (coreTool.authorizationInterceptor) {
    if (error.response && error.response.status) {
      switch (error.response.status) {
        case 400:
          if (isFirst400) {
            isFirst400 = false
            error.response.statusText = '请求错误！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst400 = true }, 5000)
          }
          break
        case 401:
          if (isFirst401) {
            isFirst401 = false
            setTimeout(() => { isFirst401 = true }, 5000)
            error.response.statusText = '会话过期，请重新登录！'
            message.error(error.response.statusText, 2)
            message.loading('正在清理缓存...', 2.5)
              .then(() => {
                coreTool.ls.remove!('coreToken')
                coreTool.ls.remove!('coreAesKey')
                router.push(PageEnum.BASE_LOGIN)
                message.success('缓存清理完成。已自动为您跳转到登录页，请重新登录！', 5)
              }, () => {})
          }
          break
        case 404:
          if (isFirst404) {
            isFirst404 = false
            error.response.statusText = `请求地址出错：${error.response.config.url}`
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst404 = true }, 5000)
          }
          break
        case 408:
          if (isFirst408) {
            isFirst408 = false
            error.response.statusText = '请求超时！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst408 = true }, 5000)
          }
          break
        case 500:
          if (isFirst500) {
            isFirst500 = false
            error.response.statusText = '连接失败，请检查！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst500 = true }, 5000)
          }
          break
        case 502:
          if (isFirst502) {
            isFirst502 = false
            error.response.statusText = '连接失败，请检查！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst502 = true }, 5000)
          }
          break
        case 504:
          if (isFirst504) {
            isFirst504 = false
            error.response.statusText = '网关超时！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst504 = true }, 5000)
          }
          break
        default:
          if (isFirst) {
            isFirst = false
            error.response.statusText = '连接失败，请检查！'
            message.error(error.response.statusText, 6)
            setTimeout(() => { isFirst = true }, 5000)
          }
          break
      }
    } else {
      message.error('连接失败，请检查！', 6)
    }
    return Promise.reject(error)
  } else {
    return Promise.reject(error)
  }
})

coreAxios.defaults.headers.common['Authorization'] = coreTool.ls.get!('coreToken') || 'token'

export default coreAxios
